package com.maisonliberte.crawller;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.maisonliberte.conf.Config;
import com.maisonliberte.dao.Dao;
import com.maisonliberte.entity.ImageInfo;
import com.maisonliberte.entity.ProductInfo;
import com.maisonliberte.enums.CrawlCategory;
import com.maisonliberte.enums.CrawlTarget;
import com.maisonliberte.enums.ImageSizeEnum;
import com.maisonliberte.exceptions.CrawlingException;
import com.maisonliberte.util.FileUtil;
import com.maisonliberte.util.HttpUtil;
import com.maisonliberte.util.ImageUtil;

abstract public class AbstractCrawler {
	
	private int endCnt = 10000;
	protected String url;
	protected String buyer = "";
	public String getBuyer() {
		return buyer;
	}

	public void setBuyer(String buyer) {
		this.buyer = buyer;
	}
	protected String charset;
	protected CrawlTarget target;
	public CrawlTarget getTarget() {
		return target;
	}

	public void setTarget(CrawlTarget target) {
		this.target = target;
	}
	protected CrawlCategory category;
	protected List<String> parsingDataList;
	protected List<ProductInfo> productList;
	
	
	public AbstractCrawler(){
		
	}
	
	public void process() throws Exception{
		
		try{
			
			if(this.category.value().isEmpty()) return;
			
			// reset	
			parsingDataList = new ArrayList<String>();
			productList = new ArrayList<ProductInfo>();
			
			parsingData(url);
			String csvData = "Url, Name, Name(JPN), Weight, Qty, Price, ConsumerPrice, ORG_Price, ORG_Carraige, Rate, EMS, FW_FEE, Commision, Spec, Staff_id, Staff_comment, Maker_id, Maker_comment, Brand_id\r\n";
			//String str =  String.format("%s,%s,%s,%s,%s", tableOther.getStaff_id(), tableOther.getStaff_comment(), tableOther.getMaker_id(), tableOther.getMaker_comment(), tableOther.getBrand_id());
			int i = 0;
			
			for(String pData : parsingDataList){
				
				try{
					ProductInfo pInfo = getProductInfo(pData);
					if(pInfo != null){
						pInfo.setCategoryInfo(category);
						System.out.println(String.format("%s Parsing Complete", pInfo.getTableInfo().getName()));
						productList.add(pInfo);
						csvData += pInfo.getCSVData() + pInfo.getOtherInfoCSVData() + "\r\n";
						i = i + 1;
					}					
					
				}catch(RuntimeException e){
					System.out.println(e);
				}catch(Exception e){
					System.out.println(e);
				}
				
				if(i > this.endCnt) break;
				
			}
			FileUtil.writeFile(csvData, Config.getInstance().csvSaveLocation);
			System.out.println("download product image start");
			downloadProductImage();
			System.out.println("download product image end");
			System.out.println("upload product image start");
			uploadProductImage();
			System.out.println("upload product image finish");
			System.out.println("update product info start");
			updateProductInfo();
			System.out.println("update product info end");
			
		} catch(CrawlingException cex){
			throw cex;
		}
		catch(Exception ex){
			throw new CrawlingException("process", ex);
		}
		
	}
	
	private String requestUrl(String _url) throws Exception {
		return HttpUtil.httpGet(_url, this.charset);
	} 
	
	private void parsingData(String _url) throws Exception {
		String nextUrl = "";
		String parsingResult = requestUrl(_url);
		if(parsingResult.isEmpty()) return;
		
		analyzeParsedData(parsingResult);
		if(!(nextUrl = getNextPage(parsingResult)).isEmpty()){
			parsingData(nextUrl);
		}
	}
	
	private void downloadProductImage() throws Exception {
		

			ImageInfo downloadImage = null;
			
			for(ProductInfo pinfo : productList){
				
				try{
					downloadImage = pinfo.getImageList().get(ImageSizeEnum.LARGE_500px).get(0);
					downloadImage.setLocalPath(String.format("%s/%s_large.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
					HttpUtil.saveAsImage(downloadImage.getImgUrl(), downloadImage.getLocalPath());

//					if(pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).size() == 0){
//						ImageInfo imgInfo = new ImageInfo("");
//						imgInfo.setLocalPath(String.format("%s/%s_middle.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
//						pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).add(imgInfo);
//						if(!ImageUtil.resizeImage(downloadImage.getLocalPath(), imgInfo.getLocalPath(), ImageSizeEnum.MIDDLE_250px)){
//							FileUtil.copyTransfer(downloadImage.getLocalPath(), imgInfo.getLocalPath());
//						}
//					}else{
//						//if(HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).get(0).getImgUrl())){
//							pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).get(0).setLocalPath(String.format("%s/%s_middle.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
//							HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).get(0).getImgUrl(), pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).get(0).getLocalPath());	
//						//}else{
//							//pinfo.getImageList().get(ImageSizeEnum.MIDDLE_250px).get(0).setLocalPath("");
//						//}
//						
//					}
					

					if(pinfo.getImageList().get(ImageSizeEnum.LIST_150px).size() == 0){
						ImageInfo imgInfo = new ImageInfo("");
						imgInfo.setLocalPath(String.format("%s/%s_list.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
						pinfo.getImageList().get(ImageSizeEnum.LIST_150px).clear();
						pinfo.getImageList().get(ImageSizeEnum.LIST_150px).add(imgInfo);
						if(!ImageUtil.resizeImage(downloadImage.getLocalPath(), imgInfo.getLocalPath(), ImageSizeEnum.LIST_150px)){
							FileUtil.copyTransfer(downloadImage.getLocalPath(), imgInfo.getLocalPath());
						}
					}else{
						if(pinfo.getListImg() != null && HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).getImgUrl())){
							String tmp = String.format("%s/%s_list_tmp.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode());
							HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).getImgUrl(), tmp);
							ImageInfo imgInfo = new ImageInfo("");
							imgInfo.setLocalPath(String.format("%s/%s_list.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
							pinfo.getImageList().get(ImageSizeEnum.LIST_150px).clear();
							pinfo.getImageList().get(ImageSizeEnum.LIST_150px).add(imgInfo);
							if(!ImageUtil.resizeImage(tmp, imgInfo.getLocalPath(), ImageSizeEnum.LIST_150px)){
								FileUtil.copyTransfer(tmp, imgInfo.getLocalPath());
							}
						}else{
							//if(HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).getImgUrl())){
								pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).setLocalPath(String.format("%s/%s_list.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
								HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).getImgUrl(), pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).getLocalPath());	
							//}else{
							//	pinfo.getImageList().get(ImageSizeEnum.LIST_150px).get(0).setLocalPath("");
							//}	
						}
					}					
					

					
//					if(pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).size() == 0){
//						ImageInfo imgInfo = new ImageInfo("");
//						imgInfo.setLocalPath(String.format("%s/%s_disp.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
//						pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).add(imgInfo);
//						if(!ImageUtil.resizeImage(downloadImage.getLocalPath(), imgInfo.getLocalPath(), ImageSizeEnum.DISPLAY_120px)){
//							FileUtil.copyTransfer(downloadImage.getLocalPath(), imgInfo.getLocalPath());
//						}
//					}else{
//						//if(HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).get(0).getImgUrl())){
//							pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).get(0).setLocalPath(String.format("%s/%s_disp.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
//							HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).get(0).getImgUrl(), pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).get(0).getLocalPath());	
//						//}else{
//						//	pinfo.getImageList().get(ImageSizeEnum.DISPLAY_120px).get(0).setLocalPath("");
//						//}
//					}
					
					if(pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).size() == 0){
						ImageInfo imgInfo = new ImageInfo("");
						imgInfo.setLocalPath(String.format("%s/%s_small.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
						pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).add(imgInfo);
						if(!ImageUtil.resizeImage(downloadImage.getLocalPath(), imgInfo.getLocalPath(), ImageSizeEnum.SMALL_80px)){
							FileUtil.copyTransfer(downloadImage.getLocalPath(), imgInfo.getLocalPath());
						}
					}else{
						//if(HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).get(0).getImgUrl())){
							pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).get(0).setLocalPath(String.format("%s/%s_small.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode()));
							HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).get(0).getImgUrl(), pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).get(0).getLocalPath());
						//}else{
						//	pinfo.getImageList().get(ImageSizeEnum.SMALL_80px).get(0).setLocalPath("");
						//}
					}
					
					for(int i = 0; i < pinfo.getImageList().get(ImageSizeEnum.OTHER_IMG).size(); i++){
						//if(HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.OTHER_IMG).get(i).getImgUrl())){
							pinfo.getImageList().get(ImageSizeEnum.OTHER_IMG).get(i).setLocalPath(String.format("%s/%s_%02d.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode(), i));
							HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.OTHER_IMG).get(i).getImgUrl(), pinfo.getImageList().get(ImageSizeEnum.OTHER_IMG).get(i).getLocalPath());	
						//}
					}
					
					//for(ImageInfo einfo : pinfo.getImageList().get(ImageSizeEnum.DETAIL_IMG)){
					for(int i = 0; i < pinfo.getImageList().get(ImageSizeEnum.DETAIL_IMG).size(); i++){
						//if(HttpUtil.existsURL(pinfo.getImageList().get(ImageSizeEnum.DETAIL_IMG).get(i).getImgUrl())){
							pinfo.getImageList().get(ImageSizeEnum.DETAIL_IMG).get(i).setLocalPath(String.format("%s/%s_detail%02d.jpg", Config.getInstance().imageSaveLocation, downloadImage.getCode(), i));
							HttpUtil.saveAsImage(pinfo.getImageList().get(ImageSizeEnum.DETAIL_IMG).get(i).getImgUrl(), pinfo.getImageList().get(ImageSizeEnum.DETAIL_IMG).get(i).getLocalPath());
						//}
					}
					
					
				}catch(RuntimeException e){
					System.out.println(e);
				}catch(Exception e){
					System.out.println(e);
				}
			}
		
		
	}
	
	private void uploadProductImage() throws Exception{
		
		try{
			String uploadPath = Config.getInstance().ftpPathList.get(target);
			
			for(ProductInfo pinfo : productList){
				int idx = getRandomeNo();
				String uploadUrl = Config.getInstance().uploadUrlList.get(idx);
				String copyPath = Config.getInstance().imageRepList.get(idx);
				System.out.println("upload url : " + uploadUrl);
				for(ImageSizeEnum sizeEnum : pinfo.getImageList().keySet()){
					for(ImageInfo einfo : pinfo.getImageList().get(sizeEnum)){

						try{
							if(einfo.getLocalPath() == null || einfo.getLocalPath().isEmpty()) continue;
							einfo.setUploadPath(String.format("%s/%s/%s", uploadPath, sizeEnum.toString(), FileUtil.getFilename(einfo.getLocalPath())));
							if(Config.getInstance().imageSaveTarget.equals("remote")){
								einfo.setImgUrl(HttpUtil.uploadProduct(uploadUrl, String.format("%s/%s/", uploadPath, sizeEnum.toString()), einfo.getLocalPath()));
							}else{
								String destPath = "";
								destPath = Config.getInstance().imageRepList.get(idx);
								String[] arrs = uploadUrl.replace("http://", "").split("/");
					            String imgUrl = arrs[0];
					            imgUrl = String.format("http://%s%s/%s/%s", imgUrl, uploadPath.replace("/public_html", ""), sizeEnum.toString(), FileUtil.getFilename(einfo.getLocalPath()));
					            System.out.println(imgUrl);
								einfo.setImgUrl(imgUrl);
								//destPath = String.format("%s%s\\%s\\%s", destPath, uploadPath.replace("/public_html", "").replace("/", "\\"), sizeEnum.toString(), FileUtil.getFilename(einfo.getLocalPath()));
								destPath = String.format("%s%s/%s/%s", destPath, uploadPath.replace("/public_html", ""), sizeEnum.toString(), FileUtil.getFilename(einfo.getLocalPath()));
								//System.out.println(destPath);
								FileUtil.copyTransfer(einfo.getLocalPath(), destPath);
							}							
						}catch(RuntimeException e){
							System.out.println(e);
						}catch(Exception e){
							System.out.println(e);
						}
					}
				}
			}
		}catch(NullPointerException ne){
			System.out.println(ne.getMessage());
			throw ne;
		}catch(Exception ex){
			throw ex;
		}
		
	}
	
	public ProductInfo getProductInfo(String data) throws Exception{
		try{
			ProductInfo pInfo = new ProductInfo(); 
			String detailUrl = getDetailUrl(data);
			if(detailUrl != null){
				pInfo.setListImg(getListImg(data));
				String detailData = requestDetailUrl(detailUrl);
				analyzerProductDetailInfo(detailData, pInfo);
				analyzerImageInfo(detailData, pInfo);
				if(pInfo.getImageList().get(ImageSizeEnum.LARGE_500px).size() == 0){
					return null;
				}
				return pInfo;
			}
			return null;
			
		}catch(Exception ex){
			
			throw ex;
		}
	}
	
	private int getRandomeNo(){
		Random random = new Random();
		int idx = random.nextInt(7);
		return idx;
		//return 0;
	}
	
	private void updateProductInfo() throws Exception{
		int no = Dao.getInstance().selectProductNumber(this.buyer);
		for(ProductInfo pinfo : productList){
			pinfo.setBuyer(this.buyer);
			pinfo.getTableInfo().setNumber(no);
			pinfo.setTarget(this.target);
			no++;
		}
		Dao.getInstance().insertProducts(productList);
	}
	
	public void setCharset(String charset) {
		this.charset = charset;
	}

	public void setCategory(CrawlCategory category) {
		this.category = category;
	}

	public void setUrl(String url) {
		this.url = url;
	}
	
	abstract public String getNextPage(String data) throws Exception;
	abstract public void analyzeParsedData(String data) throws Exception;
	abstract public String getDetailUrl(String data) throws Exception;
	abstract public void analyzerProductDetailInfo(String data, ProductInfo pInfo) throws Exception;
	abstract public void analyzerImageInfo(String data, ProductInfo pInfo) throws Exception;
	abstract public String requestDetailUrl(String url) throws Exception;
	abstract protected String getProductCode(String data);
	abstract protected String getListImg(String data);
}
